#ifndef _SPRITE_H_
#define _SPRITE_H_

#include <stdio.h>
#include <dpmi.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "utypes.h"
#include "video.h"
#include "pixmap.h"


/** @defgroup Sprite Sprite
 * @{
 *
 * Sprite related functions
 */

/** A Sprite is an "object" that contains all needed information to
 * create, animate, and destroy a pixmap.  The functions assume that
 * the background is BLUE CYAN and they take into account collision with
 * other graphical objects or the screen limits. 
 */
typedef struct {
  int x, y;            ///< current sprite position
  int width, height;   ///< sprite dimensions
  char *map;           ///< the sprite pixmap (uses read_xpm())
  Bool visibility;	   ///< the sprite visibility, i.e., if appears or not in the screen
  char type;		   ///< the sprite type
} Sprite;



#define NORMAL 0		/**< defines that represent the type of the possible pixmaps, giving them a value */
#define START 1
#define GOAL 2
#define FROG 3
#define EGG 4
#define GOAL_EGG 5

#define VISIBLE 1		/**< defines that represent the visibility of a pixmap */
#define INVISIBLE 0


#define MAX_SPEED 5		/**< each sprite maximum speed in pixels/frame */
#define RIGHT_HIT 2		/**< collision with right block (WHITE)  */
#define LEFT_HIT 3		/**< collision with left block (WHITE)   */
#define MOUSE_HIT 4		/**< collision with mouse (LIGHTMAGENTA) */

#define COLORS 256		/**< maximum number of colors accepted in read_xpm() */ 

#define WITHIN_LIMITS 0 /**< defines that represent if the pixmap is off or within the limits */
#define OFF_LIMITS -1

#define LEFT_ARROW 1	 /**< defines that represent the value of the keyboard arrows pressed */
#define RIGHT_ARROW 2
#define UP_ARROW 3
#define DOWN_ARROW 4

#define BASE_X 50		/**< base X value for the matrix (based on the screen resolution 800x600) */
#define BASE_Y 75		/**< base Y value for the matrix (based on the screen resolution 800x600) */
#define COLUMNS 7		/**< defines the number of columns and lines of the waterlilies matrix */
#define LINES 4



/*
 * there are two global variables, declared and defined here
 */
extern int x_diff;	/**< global variable with the horizontal difference between waterlilies, in pixels */
extern int y_diff;	/**< global variable with the vertical difference between waterlilies, in pixels */



/** Reads a xpm-like sprite defined in "map" (look at pixmap.h for
 * examples). Returns the address of the allocated memory where the
 * sprite was read. Updates "width" and "height" with the sprite
 * dimension.  Return NULL on error.
 * Assumes that VRES and HRES (the screen vertical and horizontal resolution)
 * are externaly defined.
 * 
 * Usage example, using the defined sprite in pixmap.h:
 * <pre>
 *   #include "pixmap.h" // defines  pic1, pic2, etc 
 *   int wd, hg;
 *   char *sprite = read_xpm(pic1, &wd, &hg);
 * </pre>
*/
char *read_xpm(char *map[], int *width, int *height);



/** Creates the structure of a new sprite with pixmap "pic", of a
 * certain type (waterlily (normal, start or goal), frog or egg) , 
 * and sets its visibility.
 * Returns NULL on invalid pixmap.
 */
Sprite * create_sprite(char *pic[], int type, int x, int y, Bool visible);



/** Moves the sprite "fig", in this case its the cursor "frog"
 * according to its attributes in memory, whose address is "base",
 * from the current position (a certain waterlily "wlily").
 * The animation detects the screen borders and doesn't let the
 * sprite move if the borders are to be trespassed.
 * It also detects collision with
 * other objects, including the player pad. Collisions with the screen
 * border generates a perfect reflection, while collision with other
 * objects generates a random perturbation in the object speed. Other
 * strategies can be devised: use quasi-elastic collision based on the
 * objects "mass" and speed, generate spin effect based on amount of
 * tangential speed direction relative to the object center of
 * "mass"...  Returns the kind of collision detected, RIGHT_HIT or
 * LEFT_HIT, if a collision with the players pad (WHITE colored!) is
 * detected.
 */
int move_sprite(Sprite *actual_wlily, int arrow, char *base);



/** The "fig" sprite is erased from memory whose address is "base"
 * and used resources released.
 */
void destroy_sprite(Sprite *fig, char *base);



/** Move in memory whose address is "base", the frog sprite (cursor), 
 * from its current position (which is over a certain waterlily) to 
 * the center of a new waterlily 'xstep' and 'ystep' away.
 * The frog is erased from its present position in xor-mode and draw
 * in the new position also in xor-mode.
 * The first time this function is called it only draws the frog at the
 * current position.
 */ 
void move_cursor(Sprite *cursor, Sprite *lily, int xstep, int ystep, char *base);



/** Draws the "fig" sprite in a certain position in the screen
 * whose address is "base".
*/
int draw_sprite(Sprite *fig, int x, int y, char *base);



/** Draws the base waterlilies in the screen, i.e., the start
 * waterlily and the goal one (with the golden egg placed on it),
 * whose address is "base". This waterlilies are always in the
 * same position, and never shrink.
 */
void draw_fixed_sprites(char *base);



/** Paints the background with light cyan (11), corresponding
 * to the lake color.
 */
void draw_background(char *base);



/** The "fig" sprite is erased from the screen (but not from memory)
 * whose address is "base", replacing the fig color by the
 * background color (11)
 */
int erase_sprite(Sprite* fig, char *base);



/** Generates a random number between 0 and num
 */
int random_num(int num);



/** Checks if the sprite (frog - cursor) new position is over a waterlily,
 * returning WITHIN_LIMITS (0) if positive, or OFF_LIMITS (-1) if otherwise.
 */
int check_new_position(Sprite *cursor, Sprite *base_lily, int x, int y, char *base);



/** Alters the sprite "fig" coordinates in the structure
 */
void alter_coords(Sprite* fig, int x, int y);






/** @} end of sprite */

#endif
